package cn.wujiangbo.recommend;

import org.ansj.domain.Result;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>测试</p>
 */
public class TfIdfTest {

    static String text = "<p>\t我国是一个海洋大国，海岸线长达3.2万多公里。中国工程院院士、哈尔滨工程大学教授杨士莪，是一个响彻中国水声界的名字。</p><p class=\"ql-align-center\"><img src=\"http://dangjian.people.com.cn/mediafile/pic/20240919/50/5234383536674664302.jpg\"></p><p class=\"ql-align-center\">\t<span style=\"color: rgb(35, 111, 161);\">杨士莪为学生讲授开学第一课。新华社发（资料照片）</span></p><p>\t作为我国水声工程学科奠基人和水声科技事业开拓者之一，杨士莪秉承“哈军工”优良传统，全力投身水声科学研究，带领团队攻克了一系列关键核心技术，推动实现了重大创新突破，完成了由我国科学家首次独立指挥和实施的大型深海水声综合考察任务，将毕生心血奉献给祖国。</p><p>\t今年3月19日，杨士莪因病在哈尔滨逝世，享年93岁。“做人做事做学问，为船为海为国防”，一大批国家急需的水声人才在他的感召下，践行强国梦想，守卫万里海疆。</p><p class=\"ql-align-center\"><img src=\"http://dangjian.people.com.cn/mediafile/pic/20240919/54/11692273472110162222.jpg\"></p><p class=\"ql-align-center\">\t<span style=\"color: rgb(35, 111, 161);\">杨士莪在大学时代的留影。新华社发（资料照片）</span></p><p>\t<strong>以身许国 为国“听海”</strong></p><p>\t杨士莪于1931年出生。从小经历战乱、流离辗转，使他萌生出“读书是为了救国和报国”的强烈渴望。新中国成立后，在清华大学物理系学习的他毅然报名参军，后来到第一海军学校（现海军大连舰艇学院）任教。</p><p>\t1952年，中国人民解放军军事工程学院开始筹建，这是我国第一所综合性高等军事技术院校。因校址在哈尔滨，被称为“哈军工”，也就是哈尔滨工程大学的前身。杨士莪再度北上。</p><p>\t1957年，杨士莪被派往苏联进修。当时，我国水声学科亟须填补空白，他便从天文学改行研究水声。因为光波、电磁波等在水中“寸步难行”，声波可以远距离传播。</p><p>\t其间，杨士莪发现有两个关键技术实验室对他这样的外国人是紧紧关闭的。“真正尖端的东西，想从国外学、从国外买，都是不可能的，只能自己干。”他暗下决心：一定要让中国的“耳朵”，听懂大海的声音，这就是一个国家、一个民族的骨气。</p><p class=\"ql-align-center\"><img src=\"http://dangjian.people.com.cn/mediafile/pic/20240919/34/7352037413823828022.jpg\"></p><p class=\"ql-align-center\">\t<span style=\"color: rgb(35, 111, 161);\">工作中的杨士莪。新华社发（资料照片）</span></p><p>\t1960年，杨士莪在回国后选择白手起家，在哈军工创建了我国第一个理工结合、配套完整、为国家战略服务的综合性水声工程专业。他挤出时间钻研理论，编写教材，推出了国际上最早集中论述水下噪声机理的著作《水下噪声原理》，国内最早的声学理论著作《声学原理》，以及《水声传播原理》等课程和教材。</p><p>\t70年多来，中国水声学科从无到有、从弱到强、从常规到精专，杨士莪始终引领前行。无论是海洋矿产勘探、船舶导航、水下作业等海洋资源开发，还是海疆保卫重任，都离不开水声学，离不开他所打下的基础。</p><p class=\"ql-align-center\"><img src=\"http://dangjian.people.com.cn/mediafile/pic/20240919/8/1505062337859525680.jpg\"></p><p class=\"ql-align-center\">\t<span style=\"color: rgb(35, 111, 161);\">20世纪80年代中期，杨士莪（左）在实验室指导学生。新华社发（资料照片）</span></p><p>\t<strong>创新不止 迈向“深蓝”</strong></p><p>\t南海，我国最深最大的海区和重要海上通道。1994年4月，一场中国水声界期盼已久的考察，终于出征了。这是我国首次具有战略意义的水声科学综合考察，堪称中国水声“从浅海迈向深海”的第一步。</p><p>\t两艘水声科学考察船悬挂着五星红旗，承载着近百名科研人员稳稳行进，杨士莪担任此次考察队队长和首席科学家。行至赤道附近，甲板温度接近70摄氏度，酷热难耐，加上淡水告罄，年过花甲的他便把船上漂着油花的压载水烧开了喝。</p><p>\t“要想‘下五洋捉鳖’，拼的就是那股劲儿，做科研就是打仗，该咬牙的时候一定得咬住。”回想当年与老师一同出海，同为中国工程院院士的杨德森仍难忘怀。</p><p>\t最早提出水声定位方法，为我国自主设计研发的“蛟龙号”载人潜水器奠定基础；主持设计并建造我国首个针对声学研究的“重力式低噪声水洞”；在制定我国水声发展规划、确定水声学科研究方向、指导重大水声科研和工程项目中，始终发挥重要作用……在我国水声科研领域，杨士莪总是走在前列。</p><p>\t2016年，国家海洋局为85岁高龄的杨士莪颁发“终身奉献海洋”纪念奖章，但他奋斗的脚步从未停下。试验设备研制、海洋水文条件监测、海试数据分析……他坚持参加科研海试和科学考察，很多项目都会过问、筹划。</p><p>\t“夕阳虽落苍山后，犹映晚霞满天红。”在90岁寿辰仪式上，杨士莪铿锵的话语振奋人心。</p><p class=\"ql-align-center\"><img src=\"http://dangjian.people.com.cn/mediafile/pic/20240919/91/12275047278048124959.jpg\"></p><p class=\"ql-align-center\">\t<span style=\"color: rgb(35, 111, 161);\">杨士莪（中）为学生讲解水声实验。新华社发（资料照片）</span></p><p>\t<strong>潜心治学 培育“后浪”</strong></p><p>\t“海洋是我们的‘蓝色国土’，需要每个人爱护、保护、守护。”在数十年的教学和人才培养中，杨士莪热衷将海洋理念传递给人们。</p><p>\t直到耄耋之年，他依旧投身教学科研一线，坚持为本科生上课，并且几乎都是站着讲课，被称为“一站到底”的“90后院士”。</p><p>\t写工整的板书、讲前沿的知识，目光平和、声如洪钟，慢条斯理、充满睿智……每当课堂结束，不少学生起立鼓掌，还有的冲上讲台请教问题、与他合影，他都一一应下。</p><p>\t学生们说，请他审阅论文，一两天就能得到反馈，修改意见写得清清楚楚。有时他到外地开会，只要一回校，第一件事就是把耽误的课补上。</p><p>\t同事们说，几乎没见过他发脾气，但他不怒自威；也未见他流露疲态或者慌乱，他总是指挥若定、沉着果断。</p><p>\t据统计，杨士莪累计培养了110多名水声专业硕士、博士研究生，其中多数已经成长为科研及学术骨干，我国水声领域的三名中国工程院院士都曾受他指导。他曾获评“全国教书育人楷模”“全国优秀科技工作者”“龙江楷模”等称号。</p><p>\t“教育就是传道授业解惑，受过教训、栽过跟头的人应该帮助年轻人少走弯路”“要把理论研究与工程实际联系起来，要把个人的前途和国家的需要结合起来”……</p><p>\t如今，铭记他的初心，追寻他的脚步，一大批能挑大梁、担重任的科技人才乘风破浪、砥砺前行，为全面推进强国建设、民族复兴伟业作出新的贡献。</p><p>\t（新华社哈尔滨9月18日电 记者杨思琪）</p>";

    public static void main(String[] args) {
        Map<String, Double> map = tfIdf(ansj(text));
        System.out.println("map.size()=================" + map.size());

        // 使用Stream API根据value排序，并限制结果为前10条
        List<Map.Entry<String, Double>> sortedEntries = map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(15) // 如果map中的条目少于15个，这将自动限制为实际条目数
                .collect(Collectors.toList());

        // 输出排序后的前10条数据
        for (Map.Entry<String, Double> entry : sortedEntries) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    public static Map<String, Double> tfIdf(List<String> docs) {
        Map<String, Integer> wordFreq = new HashMap<>();
        int totalWords = 0;
        for (String doc : docs) {
            String[] words = doc.split(" ");
            for (String word : words) {
                wordFreq.put(word, wordFreq.getOrDefault(word, 0) + 1);
                totalWords++;
            }
        }
        Map<String, Double> tfIdf = new HashMap<>();
        int docSize = docs.size();
        for (String word : wordFreq.keySet()) {
            double tf = (double) wordFreq.get(word) / totalWords;
            int docCount = 0;
            for (String doc : docs) {
                if (doc.contains(word)) {
                    docCount++;
                }
            }
            double idf = Math.log((double) docSize / (docCount + 1));
            tfIdf.put(word, tf * idf);
        }
        return tfIdf;
    }

    public static List<String> ansj(String str) {
        Set<String> Nature = new HashSet<String>();
        Nature.add("n");
        Nature.add("vn");  //只取n和vn两种词性 即名词和一部分动词
        Result result = ToAnalysis.parse(str); // 分词结果的一个封装，主要是一个List<Term>的terms

        List<Term> terms = result.getTerms(); // 拿到terms
        // System.out.println(terms.size());

        Map<String, Double> map = new HashMap<String, Double>();
        // 定义map来存储词汇名称和词的数量

        List<String> list = new ArrayList<String>();
        for (int i = 0; i < terms.size(); i++) {
            String word = terms.get(i).getName(); // 拿到词
            String natureStr = terms.get(i).getNatureStr(); // 拿到词性
            if (Nature.contains(natureStr)) // 判断set里有没有该词性，只取自己需要的
            {
                map.put(word, map.getOrDefault(word, 0.0) + 1.0);
                list.add(word);
            }
        }
        System.out.println("list.size()=================" + list.size());
        return list;
    }
}
